module frv_load_entry (
    input clk,    // Clock
    input pd_rst, // Clock Enable
    input rst_n,  // Asynchronous reset active low
    //queue pick signals
    input                       entry_in_selected,
    input                       entry_mem_selected, // mem inst
    input                       entry_dev_selected,// device inst
    input                       entry_resp_selected,
    input                       entry_ddr_selected,
    input                       entry_RAW_selected,
    input                       entry_flush_selected,
    //cache
    input                       entry_cache_miss,
    input                       entry_cache_hit,
    //ddr
    input                       entry_ddr_ack,
    //dev
    // input                       entry_dev_ack,
    input                       entry_dev_arready,
    input                       entry_dev_rvalid,
    input                       entry_dev_rresp,
    //items
    input [32-1:0]                     load_entry_addr,
    input [5:0]            load_entry_inst_id,
    input [1-1:0]                      load_entry_req_type,  //0:mem  1:dev  
    input [32-1:0]                     load_entry_resp_data,
    input [3-1:0]                      load_entry_req_info, // [1:0]: 0:word 1:half 2:byte  [2]:1: unsign 0:sign

    output [32-1:0]                    load_entry_addr_o,
    output [5:0]           load_entry_inst_id_o,
    output                             load_entry_vld_o,  
    output [4-1:0]                     load_entry_req_state_o,
    output [1-1:0]                     load_entry_req_type_o ,  //  
    output [32-1:0]                    load_entry_resp_data_o,                           // mux??
    output [3-1:0]                     load_entry_req_info_o

);


`define LOAD_EMPTY                  0
`define LOAD_WAIT                   1
`define LOAD_MEM_ACCESSED           2
`define LOAD_DEV_ACCESSED           3
`define LOAD_CACHE_MISS             4
`define LOAD_DDR_ACCESSED           5
`define LOAD_READY                  6
`define LOAD_DEV_ARREADY            7

wire load_ready=load_entry_req_state_o ==`LOAD_READY;
wire load_empty=load_entry_req_state_o ==`LOAD_EMPTY;


assign entry_dev_ack=entry_dev_rvalid & (load_entry_req_state_o==`LOAD_DEV_ARREADY);




//item en
wire  load_entry_addr_en             =entry_in_selected;
wire  load_entry_inst_id_en          =entry_in_selected;
wire  load_entry_req_type_en         =entry_in_selected;
wire  load_entry_resp_data_en        =entry_RAW_selected|entry_ddr_ack|entry_dev_ack|entry_cache_hit;
wire  load_entry_req_info_en         =entry_in_selected;



//item out
assign load_entry_vld_o=~load_empty;

dffr #(.DW(32))              load_entry_addr_ff                           (clk,rst_n,load_entry_addr_en          ,load_entry_addr          ,load_entry_addr_o);
dffr #(.DW(5+1)) load_entry_inst_id_ff                        (clk,rst_n,load_entry_inst_id_en       ,load_entry_inst_id       ,load_entry_inst_id_o);
dffr #(.DW(1))               load_entry_req_type_ff                       (clk,rst_n,load_entry_req_type_en      ,load_entry_req_type      ,load_entry_req_type_o);
dffr #(.DW(32))              load_entry_resp_data_ff                      (clk,rst_n,load_entry_resp_data_en     ,load_entry_resp_data     ,load_entry_resp_data_o);
dffr #(.DW(3))               load_entry_req_info_ff                       (clk,rst_n,load_entry_req_info_en      ,load_entry_req_info      ,load_entry_req_info_o);

logic [4-1:0] load_entry_req_state_o_next;
dffr #(.DW(4)) load_entry_req_state_o_ff (clk,rst_n,1'b1,load_entry_req_state_o_next,load_entry_req_state_o);  //rst idle
always_comb begin
    load_entry_req_state_o_next=load_entry_req_state_o;
    case (load_entry_req_state_o)
        `LOAD_EMPTY:begin
            load_entry_req_state_o_next=entry_RAW_selected? `LOAD_READY:
                                         entry_in_selected? `LOAD_WAIT :load_entry_req_state_o;  // RAW to ready
        end
        `LOAD_WAIT:begin
            load_entry_req_state_o_next=entry_flush_selected ?0                 :
                                        entry_dev_selected   ?`LOAD_DEV_ACCESSED:
                                        entry_mem_selected   ?`LOAD_MEM_ACCESSED:load_entry_req_state_o;
        end
        `LOAD_MEM_ACCESSED:begin
            load_entry_req_state_o_next=entry_flush_selected ?0                 :
                                        entry_cache_miss     ?`LOAD_CACHE_MISS:
                                        entry_cache_hit      ?`LOAD_READY     :load_entry_req_state_o;
        end
        `LOAD_DEV_ACCESSED:begin    //arvalid
            load_entry_req_state_o_next=entry_dev_arready?`LOAD_DEV_ARREADY:load_entry_req_state_o;
        end
        `LOAD_CACHE_MISS:begin
            load_entry_req_state_o_next=entry_flush_selected ?0                 :
                                        entry_ddr_selected?`LOAD_DDR_ACCESSED:load_entry_req_state_o;
        end
        `LOAD_DDR_ACCESSED:begin
            load_entry_req_state_o_next=entry_flush_selected ?0                 :
                                        entry_ddr_ack?`LOAD_READY:load_entry_req_state_o;
        end
        `LOAD_READY:begin
            load_entry_req_state_o_next=entry_flush_selected ?0                 :
                                        entry_resp_selected?`LOAD_EMPTY:load_entry_req_state_o;
        end
        `LOAD_DEV_ARREADY:begin     //rready 
            load_entry_req_state_o_next=entry_dev_rvalid & (entry_dev_rresp==0)?`LOAD_READY:load_entry_req_state_o;
        end



    endcase
end


endmodule
